package com.example.iorder;

import java.util.ArrayList;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.domain.Restaurant;
import com.example.iorder.config.Config;
import com.example.iorder.restaurant.RestaurantDetailsTabHost;
import com.example.iorder.util.HTTPClient;
import com.example.iorder.util.NavigationManager;

public class SearchResultsRestaurant extends ListActivity implements OnScrollListener {
	ListRestaurantAdapter adapter;
	private ProgressDialog progress;
	private Activity messageContext;
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        messageContext = this;
        setContentView(R.layout.search_restaurant_results);
        
        // Show loading indicator
        progress = new ProgressDialog(messageContext);
        progress.setTitle(getResources().getString(R.string.loading_title));
        progress.setMessage(getResources().getString(R.string.loading_message));
        progress.show();
        
        // Get the search criteria
        Intent intent = getIntent();
        final String searchByName = intent.getStringExtra("restName");
        final String searchByCity = intent.getStringExtra("restCity");
        
        // Start another thread to search for restaurants
        new Thread() {
        	public void run() {
        		Message msg = new Message();
        		String path = "";
        		HTTPClient httpClient = null;
        		String searchResult = "";
        		
        		try {
        			path = Config.URL_RESTAURANTS + "?name=" + searchByName + "&city=" + searchByCity;
        			httpClient = new HTTPClient(getBaseContext());
        			searchResult = httpClient.sendGETRequest(Config.IORDER_SERVER, path);
        			
        			msg.getData().putString("searchResult", searchResult);
        			searchOutputHandler.sendMessage(msg);
        		} catch (Exception e) {
        			msg.getData().putString("exception", e.toString());
        		}
        	}
        }.start();
        
        // Bind the adapter to this view
        adapter = new ListRestaurantAdapter(this);
        setListAdapter(adapter); 
        getListView().setOnScrollListener(this);
        getListView().setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View selectedView, int position, long id) {
				ResultsItemHolder selectedRestaurant = (ResultsItemHolder) selectedView.getTag();
				reserveAtSelectedRestaurant(selectedRestaurant);
				return true;
			}
		});
        
        // Add the header navigation
        RelativeLayout headerLayout = (RelativeLayout) findViewById(R.id.search_headerNavigation);
        NavigationManager.addHeaderNavigation(this, headerLayout);
    }
	
	protected void onResume() {
		super.onResume();
		NavigationManager.setCurrentTab(this, NavigationManager.TabButtons.Search);
	}
	
	@SuppressLint("HandlerLeak")
	private Handler searchOutputHandler = new Handler() {
		public void handleMessage(Message msg) {
			String newData = msg.getData().getString("searchResult");
			JSONArray records = null;
			ArrayList<Restaurant> list = new ArrayList<Restaurant>();
			int amountOfRecordsFound = 0;
			
			try {
				JSONObject jsonObject = new JSONObject(newData);
				if (jsonObject.has("data") && jsonObject.has("msg") && jsonObject.has("status")) {
					// Connection to server was successful and data was received 
					if (jsonObject.get("status").toString().equals("200")) {
						records = jsonObject.getJSONArray("data");
						
						// Convert data into list of restaurants
						for (int i = 0; i < records.length(); i++) {
							try {
								JSONObject row = records.getJSONObject(i);
								if (row != null) {
									String idString = row.optString("ID");
									String name = row.optString("Name");
									String address = row.optString("Address");
									String city = row.optString("City");
									String phoneNumber = row.optString("PhoneNumber");
									int id = Integer.parseInt(idString);
									
									Restaurant newRestaurant = new Restaurant(id, name, address, city, phoneNumber, "");
									list.add(newRestaurant);
									amountOfRecordsFound++;
								}
							} catch (Exception e) {}
						}
						
						// Update the GUI
						if (list.size() > 0) {
							try {
								adapter.setRestaurants(list);
								adapter.notifyDataSetChanged();
								progress.dismiss();
							} catch (Exception e) {
								Toast.makeText(messageContext, "GUI update exception: " + e.getMessage(), Toast.LENGTH_SHORT);
							}
						} else {
							// 0 results found
							adapter.setRestaurants(list);
							progress.dismiss();
						}
						updateViewRecordsFound(amountOfRecordsFound);
					} else {
						Toast.makeText(messageContext, "Backend server error no : " + jsonObject.get("status").toString(), Toast.LENGTH_SHORT).show();
						progress.dismiss();
					}
				} else {
					Toast.makeText(messageContext, "Faulty backend server response!", Toast.LENGTH_SHORT).show();
					progress.dismiss();
				}
			} catch (JSONException jsnE) {
				String errorMessage = "JSON Error: " + jsnE.getMessage();
				if (newData.equals("Error: No network")) {
					errorMessage = getResources().getString(R.string.no_network_connection);
				}
				Toast.makeText(messageContext, errorMessage, Toast.LENGTH_LONG).show();
				progress.dismiss();
			} catch (Exception e) {
				Toast.makeText(messageContext, "Error: " + e.getMessage(), Toast.LENGTH_SHORT).show();
				progress.dismiss();
			}
		}
	};
	
	public void onContentChanged() {
		super.onContentChanged();
		
		// Show message when no results are found
		View emptyView = findViewById(R.id.noResults);
		ListView list = getListView();
		list.setEmptyView(emptyView);
	}
	
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		boolean loadMore = firstVisibleItem + visibleItemCount >= totalItemCount;
		
		if (loadMore && visibleItemCount != totalItemCount) {
			//adapter.count += visibleItemCount;
			//adapter.notifyDataSetChanged();
		}
	}
	
	@Override
	public void onListItemClick(ListView l, View v, int position, long id) {
		View selectedItem = v; //(View) getListView().getItemAtPosition(position);
		if (selectedItem != null) {
			ResultsItemHolder selectedRestaurant = (ResultsItemHolder) selectedItem.getTag();
			if (selectedRestaurant != null) {
				// Send request to fetch restaurant details and go to restaurant details page
				// but for now, show details of selected row
				String name = selectedRestaurant.restName.getText().toString();
				String city = selectedRestaurant.restCity.getText().toString();
				String message = "You've selected: \nName: " + name + "\nCity: " + city;
				AlertDialog.Builder builder = new AlertDialog.Builder(messageContext);
				builder.setMessage(message).setTitle(R.string.alert_dialog_title);
				builder.setPositiveButton(R.string.lable_button_ok,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								// User clicked OK button
							}
						});
				AlertDialog newDialog = builder.create();
				//newDialog.show();
				Intent intent = new Intent(SearchResultsRestaurant.this, RestaurantDetailsTabHost.class);
				Bundle reservationInfo = new Bundle();
				reservationInfo.putInt(getResources().getString(R.string.key_restaurant_id), selectedRestaurant.restId);
				intent.putExtras(reservationInfo);
				startActivity(intent);
			}
		}
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		// Don't do anything
		if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {
			getListView().invalidateViews();
		}
	}
	
	private void reserveAtSelectedRestaurant(ResultsItemHolder selectedRestaurant) {
		AlertDialog.Builder builder = new AlertDialog.Builder(messageContext);
		String restaurantName = selectedRestaurant.restName.getText().toString();
		builder.setMessage("Start reservation at " + restaurantName).setTitle(R.string.alert_dialog_title);
		builder.setPositiveButton(R.string.lable_button_ok,
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int id) {
						// User clicked OK button
					}
				});
		AlertDialog newDialog = builder.create();
		newDialog.show();
	}
	
	private void updateViewRecordsFound(int amountOfRecords) {
		TextView view = (TextView) findViewById(R.id.amountRestaurantsFound);
		String plural = "";
		if (amountOfRecords > 1 || amountOfRecords == 0) {
			plural = "s";
		}
		String amountOfRecordsString = amountOfRecords + " restaurant" + plural + " gevonden.";
		view.setText(amountOfRecordsString);
	}
	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.top_navigation, menu);
		return true;
	}
	
	class ListRestaurantAdapter extends BaseAdapter {
		Context context;
		private ArrayList<Restaurant> data;
		int count = 40;
		
		public ListRestaurantAdapter(Context context) {
			this.context = context;
		}
		
		@Override
		public int getCount() {
			if (data != null)
				return data.size();
			else
				return 0;
		}

		@Override
		public Object getItem(int position) {
			return position;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// Custom results with custom view (SearchResultsItem)
			View row = convertView;
			ResultsItemHolder itemHolder = new ResultsItemHolder();
			
			if (convertView == null) {
				LayoutInflater inflater = ((Activity)context).getLayoutInflater();
				row = inflater.inflate(R.layout.search_results_item, parent, false);
				
				TextView nameView = (TextView) row.findViewById(R.id.results_rest_name);
				TextView cityView = (TextView) row.findViewById(R.id.results_rest_city);
				ImageView imageView = (ImageView) row.findViewById(R.id.results_rest_image);
				
				itemHolder.restName = nameView;
				itemHolder.restCity = cityView;
				itemHolder.restImage = imageView;
				
				row.setTag(itemHolder);
			} else {
				itemHolder = (ResultsItemHolder) row.getTag();
			}
			
			Restaurant restaurant = null;
			if (position < data.size()) {
				restaurant = data.get(position);
			}
			if (itemHolder != null) {
				if (restaurant != null) {
					itemHolder.restId = restaurant.getId();
					itemHolder.restName.setText(restaurant.getName());
					itemHolder.restCity.setText(restaurant.getAddress() + ", " + restaurant.getCity());
					itemHolder.restImage.setImageResource(R.drawable.search_icon);
				} else {
					itemHolder.restName.setText("El Pico Bello" + position);
					itemHolder.restCity.setText("Amsterdam");
					itemHolder.restImage.setImageResource(R.drawable.search_icon);
				}
			}
			
			return row;
		}
		
		public ArrayList<Restaurant> getRestaurants() { return data; }
		public void setRestaurants(ArrayList<Restaurant> newData) {
			data = newData;
		}
	}
	
	private static class ResultsItemHolder {
		public int restId;
		public TextView restName;
		public TextView restCity;
		public ImageView restImage;
	}
}
